package com.elephant.proxy.cglib;

import org.springframework.cglib.core.DebuggingClassWriter;
import org.springframework.cglib.proxy.Enhancer;

public class MyTest {
    public static void main(String[] args) {
        //动态代理创建的class文件存储到本地
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"d:\\code");
        //通过cglib动态代理获取代理对象的过程，创建调用的对象,在后续创建过程中EnhanceKey的对象
		// ，所以在进行enhancer对象创建的时候需要把EnhancerKey（newInstance）对象准备好,恰好这个对象也需要动态代理来生成


		/**
		 * 在用到cglib动态代理的时候，会创建一个Enhancer对象，这个对象会调用getKey()方法，
		 * 这个方法会返回一个EnhancerKey对象，但是这个对象也需要动态代理来生成
		 * 在生成的过程种主要是有两个Function类型的函数式接口，一个叫GET_KEY另一个是load,
		 * 并且保存到ClassLoaderData中的一个generatedClasses集合里面，方便后续进行调用。在后续回掉用到load中的
		 * apply()方法，来进行对象的代理处理，在这里生成符合规范的类名，并且生成字节码文件（有被代理的方法，在这也会进行识别处理），
		 * 并且会加入到缓存中，
		 * 后续会调用Instance方法来创建对象，不过他有两个Instance，一个是firstInstance，
		 * 也就是我们在创建EnhancerKey的时候会走这个，另一个是nextInstance()普通代理的走这个
		 *
		 * 大致流程是先根据指定的条件生成一个代理类的类名，然后在生成字节码，
		 * 最后通过反射的classForName来参加对象
		 */
		Enhancer enhancer = new Enhancer();
        //设置enhancer对象的父类

//
        enhancer.setSuperclass(MyCalculator.class);
        //设置enhancer的回调对象
        enhancer.setCallback(new MyCglib());
        //创建代理对象

        MyCalculator myCalculator = (MyCalculator) enhancer.create();
        //通过代理对象调用目标方法
        myCalculator.add(1,1);

        System.out.println(myCalculator.getClass());
    }
}